/*
 * LinkPropertiesDialog.java
 * 
 * Copyright 2008 David D. Emory
 * 
 * This file is part of Five Points. See <http://www.fpdev.org> for
 * additional information regarding the project.
 * 
 * Five Points is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Five Points is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.fpdev.apps.rtemaster.gui.dialogs;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import org.fpdev.core.basenet.BLink;
import org.fpdev.core.basenet.BaseNetGraph;
import org.fpdev.core.basenet.BNode;
import org.fpdev.apps.rtemaster.RouteMaster;
import org.fpdev.apps.rtemaster.actions.EditLinksPropertiesAction;
import org.fpdev.apps.rtemaster.gui.LinkOptionsPanel;
import org.fpdev.util.gui.GUIFactory;

/**
 *
 * @author demory
 */
public class LinkPropertiesDialog extends JDialog implements ActionListener {

  private RouteMaster av_;
  private JButton applyBtn_,  cancelBtn_;
  private JRadioButton keepTypeRBtn_,  newTypeRBtn_;
  private JComboBox typeCombo_;
  private JRadioButton keepNameRBtn_,  newNameRBtn_;
  private JTextField nameField_;
  private JRadioButton keepBProvRBtn_,  newBProvRBtn_;
  private JComboBox bProvCombo_;
  private JRadioButton keepTProvRBtn_,  newTProvRBtn_;
  private JComboBox tProvCombo_;
  private JRadioButton keepDirRBtn_,  dirTwoWayRBtn_,  dirOneWayRBtn_;
  private JComboBox dirCombo_;
  private Map<Integer, BNode> endPointLookup_;
  private boolean okPressed_;

  public LinkPropertiesDialog(Set<BLink> links, RouteMaster av) {
    super(av.getGUI(), "Link Properties", true);

    av_ = av;
    okPressed_ = false;

    // type panel

    JPanel typePanel = new JPanel(new GridLayout(1, 2));
    typePanel.setBorder(GUIFactory.createPaddedTitledBorder("Link Type", 0, 5, 5, 5));
    keepTypeRBtn_ = new JRadioButton("Keep existing", true);
    typePanel.add(keepTypeRBtn_);
    JPanel typeRightPanel = new JPanel();
    typeRightPanel.setLayout(new BoxLayout(typeRightPanel, BoxLayout.Y_AXIS));
    newTypeRBtn_ = new JRadioButton("Set all to type:");
    newTypeRBtn_.setAlignmentX(Component.LEFT_ALIGNMENT);
    typeRightPanel.add(newTypeRBtn_);
    typeCombo_ = LinkOptionsPanel.createLinkTypeComboBox();
    typeCombo_.setAlignmentX(Component.LEFT_ALIGNMENT);
    typeCombo_.addActionListener(this);
    typeRightPanel.add(typeCombo_);
    typePanel.add(typeRightPanel);
    ButtonGroup typeBtnGrp = new ButtonGroup();
    typeBtnGrp.add(keepTypeRBtn_);
    typeBtnGrp.add(newTypeRBtn_);



    // name panel

    JPanel namePanel = new JPanel(new GridLayout(1, 2));
    namePanel.setBorder(GUIFactory.createPaddedTitledBorder("Link Name", 0, 5, 5, 5));
    keepNameRBtn_ = new JRadioButton("Keep existing", true);
    namePanel.add(keepNameRBtn_);
    JPanel nameRightPanel = new JPanel();
    nameRightPanel.setLayout(new BoxLayout(nameRightPanel, BoxLayout.Y_AXIS));
    newNameRBtn_ = new JRadioButton("Rename all:");
    newNameRBtn_.setAlignmentX(Component.LEFT_ALIGNMENT);
    nameRightPanel.add(newNameRBtn_);
    nameField_ = GUIFactory.newTextField("", 64, 180);
    nameField_.setAlignmentX(Component.LEFT_ALIGNMENT);
    nameField_.addKeyListener(new KeyAdapter() {

      @Override
      public void keyPressed(KeyEvent e) {
        newNameRBtn_.setSelected(true);
      }
    });
    nameRightPanel.add(nameField_);
    namePanel.add(nameRightPanel);
    ButtonGroup nameBtnGrp = new ButtonGroup();
    nameBtnGrp.add(keepNameRBtn_);
    nameBtnGrp.add(newNameRBtn_);

    // bike provisions panel

    JPanel bProvPanel = new JPanel(new GridLayout(1, 2));
    bProvPanel.setBorder(GUIFactory.createPaddedTitledBorder("Bicycle Provisions (Applied to Street Links Only)", 0, 5, 5, 5));
    keepBProvRBtn_ = new JRadioButton("Keep existing", true);
    bProvPanel.add(keepBProvRBtn_);
    JPanel bProvRightPanel = GUIFactory.newColumnPanel();
    newBProvRBtn_ = new JRadioButton("Apply to all:");
    newBProvRBtn_.setAlignmentX(Component.LEFT_ALIGNMENT);
    bProvRightPanel.add(newBProvRBtn_);
    bProvCombo_ = LinkOptionsPanel.createBikeProvisionsComboBox();
    bProvCombo_.setAlignmentX(Component.LEFT_ALIGNMENT);
    bProvCombo_.addActionListener(this);
    bProvRightPanel.add(bProvCombo_);
    bProvPanel.add(bProvRightPanel);
    ButtonGroup bProvBtnGrp = new ButtonGroup();
    bProvBtnGrp.add(keepBProvRBtn_);
    bProvBtnGrp.add(newBProvRBtn_);

    // transit provisions panel

    JPanel tProvPanel = new JPanel(new GridLayout(1, 2));
    tProvPanel.setBorder(GUIFactory.createPaddedTitledBorder("Transit Provisions (Applied to Street Links Only)", 0, 5, 5, 5));
    keepTProvRBtn_ = new JRadioButton("Keep existing", true);
    tProvPanel.add(keepTProvRBtn_);
    JPanel tProvRightPanel = GUIFactory.newColumnPanel();
    newTProvRBtn_ = new JRadioButton("Apply to all:");
    newTProvRBtn_.setAlignmentX(Component.LEFT_ALIGNMENT);
    tProvRightPanel.add(newTProvRBtn_);
    tProvCombo_ = LinkOptionsPanel.createTransitProvisionsComboBox();
    tProvCombo_.setAlignmentX(Component.LEFT_ALIGNMENT);
    tProvCombo_.addActionListener(this);
    tProvRightPanel.add(tProvCombo_);
    tProvPanel.add(tProvRightPanel);
    ButtonGroup tProvBtnGrp = new ButtonGroup();
    tProvBtnGrp.add(keepTProvRBtn_);
    tProvBtnGrp.add(newTProvRBtn_);


    // direction panel

    JPanel dirPanel = new JPanel();
    dirPanel.setBorder(GUIFactory.createPaddedTitledBorder("Direction (Applied to Street Links Only)", 0, 5, 5, 5));

    BaseNetGraph graph = new BaseNetGraph(links.iterator());
    if (!graph.isSimplePath()) {
      dirPanel.setLayout(new BorderLayout());

      JPanel labelPanel = new JPanel();
      labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.X_AXIS));
      labelPanel.add(Box.createHorizontalGlue());
      labelPanel.add(GUIFactory.newLabel("(Selected links must form continuous linear path)"));
      labelPanel.add(Box.createHorizontalGlue());

      dirPanel.add(labelPanel, BorderLayout.CENTER);
    } else {
      dirPanel.setLayout(new GridLayout(1, 2));
      keepDirRBtn_ = new JRadioButton("Keep existing", true);
      dirPanel.add(keepDirRBtn_);
      JPanel dirRightPanel = new JPanel();
      dirRightPanel.setLayout(new BoxLayout(dirRightPanel, BoxLayout.Y_AXIS));
      dirOneWayRBtn_ = new JRadioButton("Make all one-way");
      dirOneWayRBtn_.setAlignmentX(Component.LEFT_ALIGNMENT);
      dirRightPanel.add(dirOneWayRBtn_);

      JPanel oneWayStartPanel = new JPanel();
      oneWayStartPanel.setLayout(new BoxLayout(oneWayStartPanel, BoxLayout.X_AXIS));
      oneWayStartPanel.add(Box.createHorizontalStrut(22));
      oneWayStartPanel.add(GUIFactory.newLabel("Origin: "));
      dirCombo_ = GUIFactory.newComboBox(120);
      endPointLookup_ = new HashMap<Integer, BNode>();
      int dc = 0;
      for (Iterator<BNode> ptIter = graph.getEndPoints().iterator(); ptIter.hasNext();) {
        BNode n = ptIter.next();
        dirCombo_.addItem(n.getDisplayName(av_.getEngine().getBaseNet()));
        endPointLookup_.put(dc++, n);
      }
      dirCombo_.addActionListener(this);
      oneWayStartPanel.add(dirCombo_);
      oneWayStartPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
      dirRightPanel.add(oneWayStartPanel);

      dirTwoWayRBtn_ = new JRadioButton("Make all two-way");
      dirTwoWayRBtn_.setAlignmentX(Component.LEFT_ALIGNMENT);
      dirRightPanel.add(dirTwoWayRBtn_);

      dirPanel.add(dirRightPanel);
      ButtonGroup dirBtnGrp = new ButtonGroup();
      dirBtnGrp.add(keepDirRBtn_);
      dirBtnGrp.add(dirTwoWayRBtn_);
      dirBtnGrp.add(dirOneWayRBtn_);
    }


    // button row

    applyBtn_ = new JButton("Apply Changes");
    applyBtn_.addActionListener(this);
    cancelBtn_ = new JButton("Cancel");
    cancelBtn_.addActionListener(this);


    // button row
    JPanel btnRow = new JPanel();
    btnRow.setLayout(new BoxLayout(btnRow, BoxLayout.X_AXIS));
    btnRow.add(Box.createHorizontalGlue());
    btnRow.add(applyBtn_);
    btnRow.add(Box.createHorizontalStrut(5));
    btnRow.add(cancelBtn_);
    btnRow.add(Box.createHorizontalGlue());


    // main content panel 

    JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));

    int linkCount = links.size();
    JLabel topLabel = GUIFactory.newLabel("Changes will be applied to " + linkCount + " currently selected link" + (linkCount > 1 ? "s" : ""));
    topLabel.setAlignmentX(CENTER_ALIGNMENT);
    mainPanel.add(topLabel);
    mainPanel.add(Box.createVerticalStrut(3));
    mainPanel.add(typePanel);
    mainPanel.add(Box.createVerticalStrut(3));
    mainPanel.add(namePanel);
    mainPanel.add(Box.createVerticalStrut(3));
    mainPanel.add(bProvPanel);
    mainPanel.add(Box.createVerticalStrut(3));
    mainPanel.add(tProvPanel);
    mainPanel.add(Box.createVerticalStrut(3));
    mainPanel.add(dirPanel);

    mainPanel.add(Box.createVerticalGlue());
    mainPanel.add(Box.createVerticalStrut(6));
    mainPanel.add(btnRow);

    mainPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
    getContentPane().add(mainPanel);

    this.setPreferredSize(new Dimension(420, 480));
    this.pack();
    this.setLocation((av.getGUI().getWidth() / 2) - getWidth() / 2 + av.getGUI().getX(),
            (av.getGUI().getHeight() / 2) - getHeight() / 2 + av.getGUI().getY());

    setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {

    if (e.getSource() == applyBtn_) {
      okPressed_ = true;
      setVisible(false);
    } else if (e.getSource() == cancelBtn_) {
      setVisible(false);
    } else if (e.getSource() == typeCombo_) {
      newTypeRBtn_.setSelected(true);
    } else if (e.getSource() == bProvCombo_) {
      newBProvRBtn_.setSelected(true);
    } else if (e.getSource() == tProvCombo_) {
      newTProvRBtn_.setSelected(true);
    } else if (e.getSource() == dirCombo_) {
      dirOneWayRBtn_.setSelected(true);
    }

  /*
  private JRadioButton keepNameRBtn_, newNameRBtn_;
  private JTextField nameField_;
   */

  }

  public boolean okPressed() {
    return okPressed_;
  }

  public Integer getNewType() {
    return newTypeRBtn_.isSelected() ? getSelectedCBItemNumber(typeCombo_) : null;
  }

  public String getNewName() {
    return newNameRBtn_.isSelected() ? nameField_.getText() : null;
  }

  public Integer getNewTrnProv() {
    return newTProvRBtn_.isSelected() ? getSelectedCBItemNumber(tProvCombo_) : null;
  }

  public Integer getNewBPProv() {
    return newBProvRBtn_.isSelected() ? getSelectedCBItemNumber(bProvCombo_) : null;
  }

  public EditLinksPropertiesAction.Direction getDirection() {
    if(dirOneWayRBtn_ == null) return EditLinksPropertiesAction.Direction.NO_CHANGE;
    
    if (dirOneWayRBtn_.isSelected()) {
      return EditLinksPropertiesAction.Direction.ONE_WAY;
    }
    if (dirTwoWayRBtn_.isSelected()) {
      return EditLinksPropertiesAction.Direction.TWO_WAY;
    }
    return EditLinksPropertiesAction.Direction.NO_CHANGE;
  }

  public BNode getOneWayOrigin() {
    if(dirOneWayRBtn_ == null) return null;
    return dirOneWayRBtn_.isSelected() ? endPointLookup_.get(dirCombo_.getSelectedIndex()) : null;
  }

  private int getSelectedCBItemNumber(JComboBox cb) {
    return Integer.parseInt(((String) cb.getSelectedItem()).split("\\.")[0]);
  }
}
